package com.shop.cereshop.app.utils;

import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 封装一些常用方法
 */
@Component
public class RedisUtil {
    @Resource
    private RedisTemplate<String, String> redisTemplate;

    // ==================== Hash 结构点赞功能 ====================

    /**
     * 点赞加一（使用Hash结构）
     *
     * @param hashKey Hash的key，例如：like:post 或 like:comment
     * @param itemKey Hash中的field，例如：123 或 456
     * @return 点赞后的总数
     */
    @Async
    public Long incrementLike(String hashKey, String itemKey) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        return hashOps.increment(hashKey, itemKey, 1L);
    }

    /**
     * 点赞加一（使用Hash结构，带过期时间）
     *
     * @param hashKey Hash的key
     * @param itemKey Hash中的field
     * @param timeout 过期时间
     * @param unit 时间单位
     * @return 点赞后的总数
     */
    @Async
    public Long incrementLike(String hashKey, String itemKey, long timeout, TimeUnit unit) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        Long result = hashOps.increment(hashKey, itemKey, 1L);
        // 设置Hash的过期时间
        redisTemplate.expire(hashKey, timeout, unit);
        return result;
    }

    /**
     * 取消点赞减一（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @param itemKey Hash中的field
     * @return 取消点赞后的总数（支持负数）
     */
    @Async
    public Long decrementLike(String hashKey, String itemKey) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        Long result = hashOps.increment(hashKey, itemKey, -1L);
        return result;
    }

    /**
     * 获取点赞总数（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @param itemKey Hash中的field
     * @return 点赞总数，如果不存在返回0
     */
    public Long getLikeCount(String hashKey, String itemKey) {
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        Object value = hashOps.get(hashKey, itemKey);
        
        if (value == null) {
            return 0L;
        }
        
        if (value instanceof Integer) {
            return ((Integer) value).longValue();
        } else if (value instanceof Long) {
            return (Long) value;
        } else if (value instanceof String) {
            try {
                return Long.parseLong((String) value);
            } catch (NumberFormatException e) {
                return 0L;
            }
        }
        
        return 0L;
    }

    /**
     * 设置点赞总数（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @param itemKey Hash中的field
     * @param count 点赞总数
     */
    public void setLikeCount(String hashKey, String itemKey, Long count) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        if (count <= 0) {
            hashOps.delete(hashKey, itemKey);
        } else {
            hashOps.put(hashKey, itemKey, count);
        }
    }

    /**
     * 删除点赞记录（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @param itemKey Hash中的field
     * @return 是否删除成功
     */
    public Boolean deleteLike(String hashKey, String itemKey) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        return hashOps.delete(hashKey, itemKey) > 0;
    }

    /**
     * 检查点赞记录是否存在（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @param itemKey Hash中的field
     * @return 是否存在
     */
    public Boolean hasLike(String hashKey, String itemKey) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        return hashOps.hasKey(hashKey, itemKey);
    }

    /**
     * 批量获取点赞总数（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @param itemKeys Hash中的field数组
     * @return 点赞总数Map
     */
    public Map<String, Long> getLikeCounts(String hashKey, String... itemKeys) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        Map<String, Long> result = new HashMap<>();

        for (String itemKey : itemKeys) {
            Long count = hashOps.get(hashKey, itemKey);
            result.put(itemKey, count == null ? 0L : count);
        }
        return result;
    }

    /**
     * 获取Hash中所有数据（通用方法）
     *
     * @param hashKey Hash的key
     * @return 所有数据Map
     */
    public Map<String, Long> getAllHashData(String hashKey) {
        HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
        Map<String, Object> rawData = hashOps.entries(hashKey);
        Map<String, Long> result = new HashMap<>();
        
        for (Map.Entry<String, Object> entry : rawData.entrySet()) {
            Object value = entry.getValue();
            Long longValue = 0L;
            
            if (value instanceof Integer) {
                longValue = ((Integer) value).longValue();
            } else if (value instanceof Long) {
                longValue = (Long) value;
            } else if (value instanceof String) {
                try {
                    longValue = Long.parseLong((String) value);
                } catch (NumberFormatException e) {
                    longValue = 0L;
                }
            }
            
            result.put(entry.getKey(), longValue);
        }
        
        return result;
    }

    /**
     * 获取Hash中所有点赞记录（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @return 所有点赞记录
     */
    public Map<String, Long> getAllLikeCounts(String hashKey) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        return hashOps.entries(hashKey);
    }

    /**
     * 获取Hash中点赞记录的数量（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @return 记录数量
     */
    public Long getLikeRecordCount(String hashKey) {
        HashOperations<String, String, Long> hashOps = redisTemplate.opsForHash();
        return hashOps.size(hashKey);
    }

    /**
     * 删除整个Hash（使用Hash结构）
     *
     * @param hashKey Hash的key
     * @return 是否删除成功
     */
    public Boolean deleteHash(String hashKey) {
        return redisTemplate.delete(hashKey);
    }

    // ==================== 用户点赞记录管理（使用Set结构） ====================

    /**
     * 用户点赞（使用Set记录用户点赞状态）
     *
     * @param userLikeKey 用户点赞记录的key，例如：user:like:post:123
     * @param userId 用户ID
     * @return 是否点赞成功
     */
    public Boolean userLike(String userLikeKey, String userId) {
        SetOperations<String, String> setOps = redisTemplate.opsForSet();
        return setOps.add(userLikeKey, userId) > 0;
    }

    /**
     * 用户取消点赞（使用Set记录用户点赞状态）
     *
     * @param userLikeKey 用户点赞记录的key
     * @param userId 用户ID
     * @return 是否取消点赞成功
     */
    public Boolean userUnlike(String userLikeKey, String userId) {
        SetOperations<String, String> setOps = redisTemplate.opsForSet();
        return setOps.remove(userLikeKey, userId) > 0;
    }

    /**
     * 检查用户是否已点赞（使用Set记录用户点赞状态）
     *
     * @param userLikeKey 用户点赞记录的key
     * @param userId 用户ID
     * @return 是否已点赞
     */
    public Boolean isUserLiked(String userLikeKey, String userId) {
        SetOperations<String, String> setOps = redisTemplate.opsForSet();
        return setOps.isMember(userLikeKey, userId);
    }

    /**
     * 获取点赞用户列表（使用Set记录用户点赞状态）
     *
     * @param userLikeKey 用户点赞记录的key
     * @return 点赞用户ID集合
     */
    public Set<String> getLikedUsers(String userLikeKey) {
        SetOperations<String, String> setOps = redisTemplate.opsForSet();
        return setOps.members(userLikeKey);
    }

    /**
     * 获取点赞用户数量（使用Set记录用户点赞状态）
     *
     * @param userLikeKey 用户点赞记录的key
     * @return 点赞用户数量
     */
    public Long getLikedUserCount(String userLikeKey) {
        SetOperations<String, String> setOps = redisTemplate.opsForSet();
        return setOps.size(userLikeKey);
    }

    /**
     * 设置用户点赞记录过期时间
     *
     * @param userLikeKey 用户点赞记录的key
     * @param timeout 过期时间
     * @param unit 时间单位
     */
    public void setUserLikeExpire(String userLikeKey, long timeout, TimeUnit unit) {
        redisTemplate.expire(userLikeKey, timeout, unit);
    }

    // ==================== 兼容性方法（保持原有接口） ====================

    /**
     * 点赞加一（兼容性方法，内部使用Hash结构）
     *
     * @param key 完整的key，例如：like:post:123
     * @return 点赞后的总数
     */
    public Long incrementLike(String key) {
        String[] parts = key.split(":", 3);
        if (parts.length >= 3) {
            String hashKey = parts[0] + ":" + parts[1]; // like:post
            String itemKey = parts[2]; // 123
            return incrementLike(hashKey, itemKey);
        }
        return 0L;
    }

    /**
     * 取消点赞减一（兼容性方法，内部使用Hash结构）
     *
     * @param key 完整的key
     * @return 取消点赞后的总数
     */
    public Long decrementLike(String key) {
        String[] parts = key.split(":", 3);
        if (parts.length >= 3) {
            String hashKey = parts[0] + ":" + parts[1];
            String itemKey = parts[2];
            return decrementLike(hashKey, itemKey);
        }
        return 0L;
    }

    /**
     * 获取点赞总数（兼容性方法，内部使用Hash结构）
     *
     * @param key 完整的key
     * @return 点赞总数
     */
    public Integer getLikeCount(String key) {
        String[] parts = key.split(":", 3);
        if (parts.length >= 3) {
            String hashKey = parts[0] + ":" + parts[1];
            String itemKey = parts[2];
            Long count = getLikeCount(hashKey, itemKey);
            return count.intValue();
        }
        return 0;
    }
}
